{
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Genetic Algorithm"
      ],
      "metadata": {
        "nteract": {
          "transient": {
            "deleting": false
          }
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import warnings\n",
        "warnings.filterwarnings(\"ignore\")\n",
        "\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "import pandas as pd\n",
        "import random\n",
        "\n",
        "from sklearn.model_selection import train_test_split\n",
        "\n",
        "# yahoo finance is used to fetch data \n",
        "import yfinance as yf\n",
        "yf.pdr_override()"
      ],
      "outputs": [],
      "execution_count": 1,
      "metadata": {
        "collapsed": true,
        "jupyter": {
          "source_hidden": false,
          "outputs_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        },
        "execution": {
          "iopub.status.busy": "2023-10-31T22:09:23.456Z",
          "iopub.execute_input": "2023-10-31T22:09:23.459Z",
          "shell.execute_reply": "2023-10-31T22:09:24.407Z",
          "iopub.status.idle": "2023-10-31T22:09:24.391Z"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# input\n",
        "symbol = 'AMD'\n",
        "start = '2014-01-01'\n",
        "end = '2019-01-01'\n",
        "\n",
        "# Read data \n",
        "dataset = yf.download(symbol,start,end)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[*********************100%***********************]  1 of 1 completed\n"
          ]
        }
      ],
      "execution_count": 2,
      "metadata": {
        "collapsed": true,
        "jupyter": {
          "source_hidden": false,
          "outputs_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        },
        "execution": {
          "iopub.status.busy": "2023-10-31T22:09:24.397Z",
          "iopub.execute_input": "2023-10-31T22:09:24.400Z",
          "iopub.status.idle": "2023-10-31T22:09:24.777Z",
          "shell.execute_reply": "2023-10-31T22:09:24.796Z"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "dataset['Open_Close'] = (dataset['Open'] - dataset['Adj Close'])/dataset['Open']\n",
        "dataset['High_Low'] = (dataset['High'] - dataset['Low'])/dataset['Low']\n",
        "dataset['Increase_Decrease'] = np.where(dataset['Volume'].shift(-1) > dataset['Volume'],1,0)\n",
        "dataset['Buy_Sell_on_Open'] = np.where(dataset['Open'].shift(-1) > dataset['Open'],1,0)\n",
        "dataset['Buy_Sell'] = np.where(dataset['Adj Close'].shift(-1) > dataset['Adj Close'],1,0)\n",
        "dataset['Returns'] = dataset['Adj Close'].pct_change()\n",
        "dataset = dataset.dropna()\n",
        "dataset.head()\n",
        "\n",
        "# View Columns\n",
        "dataset.head()"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 3,
          "data": {
            "text/plain": "            Open  High   Low  Close  Adj Close    Volume  Open_Close  \\\nDate                                                                   \n2014-01-03  3.98  4.00  3.88   4.00       4.00  22887200   -0.005025   \n2014-01-06  4.01  4.18  3.99   4.13       4.13  42398300   -0.029925   \n2014-01-07  4.19  4.25  4.11   4.18       4.18  42932100    0.002387   \n2014-01-08  4.23  4.26  4.14   4.18       4.18  30678700    0.011820   \n2014-01-09  4.20  4.23  4.05   4.09       4.09  30667600    0.026190   \n\n            High_Low  Increase_Decrease  Buy_Sell_on_Open  Buy_Sell   Returns  \nDate                                                                           \n2014-01-03  0.030928                  1                 1         1  0.012658  \n2014-01-06  0.047619                  1                 1         1  0.032500  \n2014-01-07  0.034063                  0                 1         0  0.012106  \n2014-01-08  0.028986                  0                 0         0  0.000000  \n2014-01-09  0.044444                  0                 0         1 -0.021531  ",
            "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Open</th>\n      <th>High</th>\n      <th>Low</th>\n      <th>Close</th>\n      <th>Adj Close</th>\n      <th>Volume</th>\n      <th>Open_Close</th>\n      <th>High_Low</th>\n      <th>Increase_Decrease</th>\n      <th>Buy_Sell_on_Open</th>\n      <th>Buy_Sell</th>\n      <th>Returns</th>\n    </tr>\n    <tr>\n      <th>Date</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2014-01-03</th>\n      <td>3.98</td>\n      <td>4.00</td>\n      <td>3.88</td>\n      <td>4.00</td>\n      <td>4.00</td>\n      <td>22887200</td>\n      <td>-0.005025</td>\n      <td>0.030928</td>\n      <td>1</td>\n      <td>1</td>\n      <td>1</td>\n      <td>0.012658</td>\n    </tr>\n    <tr>\n      <th>2014-01-06</th>\n      <td>4.01</td>\n      <td>4.18</td>\n      <td>3.99</td>\n      <td>4.13</td>\n      <td>4.13</td>\n      <td>42398300</td>\n      <td>-0.029925</td>\n      <td>0.047619</td>\n      <td>1</td>\n      <td>1</td>\n      <td>1</td>\n      <td>0.032500</td>\n    </tr>\n    <tr>\n      <th>2014-01-07</th>\n      <td>4.19</td>\n      <td>4.25</td>\n      <td>4.11</td>\n      <td>4.18</td>\n      <td>4.18</td>\n      <td>42932100</td>\n      <td>0.002387</td>\n      <td>0.034063</td>\n      <td>0</td>\n      <td>1</td>\n      <td>0</td>\n      <td>0.012106</td>\n    </tr>\n    <tr>\n      <th>2014-01-08</th>\n      <td>4.23</td>\n      <td>4.26</td>\n      <td>4.14</td>\n      <td>4.18</td>\n      <td>4.18</td>\n      <td>30678700</td>\n      <td>0.011820</td>\n      <td>0.028986</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0.000000</td>\n    </tr>\n    <tr>\n      <th>2014-01-09</th>\n      <td>4.20</td>\n      <td>4.23</td>\n      <td>4.05</td>\n      <td>4.09</td>\n      <td>4.09</td>\n      <td>30667600</td>\n      <td>0.026190</td>\n      <td>0.044444</td>\n      <td>0</td>\n      <td>0</td>\n      <td>1</td>\n      <td>-0.021531</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
          },
          "metadata": {}
        }
      ],
      "execution_count": 3,
      "metadata": {
        "collapsed": true,
        "jupyter": {
          "source_hidden": false,
          "outputs_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        },
        "execution": {
          "iopub.status.busy": "2023-10-31T22:09:24.783Z",
          "iopub.execute_input": "2023-10-31T22:09:24.788Z",
          "shell.execute_reply": "2023-10-31T22:09:24.898Z",
          "iopub.status.idle": "2023-10-31T22:09:24.848Z"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "X = np.array(dataset['Open'].values)\n",
        "y = dataset['Increase_Decrease'].values\n",
        "\n",
        "X_train, X_test, y_train, y_test = train_test_split(X, y, \n",
        "                                   test_size=0.4, random_state=42)"
      ],
      "outputs": [],
      "execution_count": 4,
      "metadata": {
        "collapsed": true,
        "jupyter": {
          "source_hidden": false,
          "outputs_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        },
        "execution": {
          "shell.execute_reply": "2023-10-31T22:09:24.901Z",
          "iopub.status.busy": "2023-10-31T22:09:24.854Z",
          "iopub.execute_input": "2023-10-31T22:09:24.857Z",
          "iopub.status.idle": "2023-10-31T22:09:24.862Z"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Define the fitness function (e.g., a simple moving average crossover strategy)\n",
        "def fitness_function(strategy, X_train, X_test, y_train, y_test):\n",
        "    # Implement your trading strategy and calculate profit or loss\n",
        "    # Example: Buy when short-term MA > long-term MA, and sell when the opposite is true\n",
        "    profit = 0\n",
        "    for i in range(1, len(X_test)):\n",
        "        if strategy[i] > strategy[i - 1] and y_test[i] == 1:\n",
        "            profit += X_test[i] - X_test[i - 1]\n",
        "        elif strategy[i] < strategy[i - 1] and y_test[i] == 0:\n",
        "            profit += X_test[i - 1] - X_test[i]\n",
        "    return profit\n",
        "\n",
        "# Create an initial population\n",
        "def initialize_population(pop_size, strategy_length):\n",
        "    population = []\n",
        "    for _ in range(pop_size):\n",
        "        strategy = [random.randint(0, 1) for _ in range(strategy_length)]\n",
        "        population.append(strategy)\n",
        "    return population\n",
        "\n",
        "# Genetic algorithm\n",
        "def genetic_algorithm(X_train, X_test, y_train, y_test, pop_size, generations):\n",
        "    strategy_length = len(X_test)  # Length of the trading strategy\n",
        "    population = initialize_population(pop_size, strategy_length)\n",
        "\n",
        "    for generation in range(generations):\n",
        "        # Evaluate fitness of the population\n",
        "        fitness_scores = [fitness_function(strategy, X_train, X_test, y_train, y_test) for strategy in population]\n",
        "\n",
        "        # Select the top-performing individuals\n",
        "        selected_population = []\n",
        "        for _ in range(pop_size):\n",
        "            idx1, idx2 = random.sample(range(pop_size), 2)\n",
        "            if fitness_scores[idx1] > fitness_scores[idx2]:\n",
        "                selected_population.append(population[idx1])\n",
        "            else:\n",
        "                selected_population.append(population[idx2])\n",
        "\n",
        "        # Crossover\n",
        "        new_population = []\n",
        "        for i in range(0, pop_size, 2):\n",
        "            parent1 = selected_population[i]\n",
        "            parent2 = selected_population[i + 1]\n",
        "            crossover_point = random.randint(1, strategy_length - 1)\n",
        "            child1 = parent1[:crossover_point] + parent2[crossover_point:]\n",
        "            child2 = parent2[:crossover_point] + parent1[crossover_point:]\n",
        "            new_population.extend([child1, child2])\n",
        "\n",
        "        # Mutation\n",
        "        mutation_rate = 0.01  # Adjust as needed\n",
        "        for i in range(pop_size):\n",
        "            if random.random() < mutation_rate:\n",
        "                mutation_point = random.randint(0, strategy_length - 1)\n",
        "                population[i][mutation_point] = 1 - population[i][mutation_point]\n",
        "\n",
        "        population = new_population\n",
        "\n",
        "    # Find the best-performing individual\n",
        "    best_strategy = max(population, key=lambda x: fitness_function(x, X_train, X_test, y_train, y_test))\n",
        "    return best_strategy"
      ],
      "outputs": [],
      "execution_count": 5,
      "metadata": {
        "collapsed": true,
        "jupyter": {
          "source_hidden": false,
          "outputs_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        },
        "execution": {
          "shell.execute_reply": "2023-10-31T22:09:24.903Z",
          "iopub.status.busy": "2023-10-31T22:09:24.867Z",
          "iopub.execute_input": "2023-10-31T22:09:24.870Z",
          "iopub.status.idle": "2023-10-31T22:09:24.875Z"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Example usage\n",
        "best_strategy = genetic_algorithm(X_train, X_test, y_train, y_test, pop_size=100, generations=100)\n",
        "print(\"Best strategy:\", best_strategy)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Best strategy: [0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1]\n"
          ]
        }
      ],
      "execution_count": 6,
      "metadata": {
        "collapsed": true,
        "jupyter": {
          "source_hidden": false,
          "outputs_hidden": false
        },
        "nteract": {
          "transient": {
            "deleting": false
          }
        },
        "execution": {
          "iopub.status.busy": "2023-10-31T22:09:24.881Z",
          "iopub.execute_input": "2023-10-31T22:09:24.885Z",
          "iopub.status.idle": "2023-10-31T22:09:26.184Z",
          "shell.execute_reply": "2023-10-31T22:09:26.195Z"
        }
      }
    }
  ],
  "metadata": {
    "kernel_info": {
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.7.6",
      "mimetype": "text/x-python",
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "pygments_lexer": "ipython3",
      "nbconvert_exporter": "python",
      "file_extension": ".py"
    },
    "kernelspec": {
      "argv": [
        "C:/Users/Tin Hang/anaconda3\\python.exe",
        "-m",
        "ipykernel_launcher",
        "-f",
        "{connection_file}"
      ],
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "nteract": {
      "version": "0.28.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}